package com.jichaoyun.sys.controller;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jichaoyun.common.ex.MyException;
import com.jichaoyun.common.utils.ExcelStyleUtils;
import com.jichaoyun.model.app.AppCollection;
import com.jichaoyun.model.entity.StationInfo;

import com.jichaoyun.common.model.Result;
import com.jichaoyun.model.entity.Menu;
import com.jichaoyun.model.entity.User;
import com.jichaoyun.model.vo.UserRegVo;
import com.jichaoyun.model.vo.UserVo;
import com.jichaoyun.sys.mapper.AppCollectionMapper;
import com.jichaoyun.sys.mapper.StationInfoMapper;
import com.jichaoyun.sys.service.IMenuService;
import com.jichaoyun.sys.service.IRoleService;
import com.jichaoyun.sys.service.IUserService;
import com.jichaoyun.util.JwtUtil;
import com.jichaoyun.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
//@RestController做json的视图封装处理

@Api(tags = {"App用户接口列表"})
@RequestMapping("/sys/user")
// @CrossOrigin   跨域处理，只会在这个control类生效，这里在全局进行配置的操作
public class UserController {

    @Autowired
    private IMenuService menuService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Resource
    private AppCollectionMapper appCollectionMapper;

    @ApiOperation("用户管理，用户注册")
    @PostMapping("/reg")
    public Result<Void> reg(@RequestBody UserRegVo reg) {//@RequestBody是做json字符串的转换
        this.userService.reg(reg);
        return Result.success("注册成功");
    }


    @ApiOperation("用户登陆")
    @GetMapping("/login")
    public Result<Map<String,Object>> login(String username, String password, HttpSession session){
        try{
            Map<String,Object> map = new HashMap<>();
            User data = userService.login(username,password);
            map.put("id",data.getId());
            map.put("date",System.currentTimeMillis());
            String jwtToken = JwtUtil.createJwtToken(map);
            map.put("user",data);
            //设置用户的登录时间和过期时间，并存入redis
            data.setLastloginTime(LocalDateTime.now());
            data.setExpireTime(data.getLastloginTime().plusMinutes(30));

            RedisUtil redisUtil = new RedisUtil();

            UserVo userVo = new UserVo();
            //将data里面的时间类型做个转换
            BeanUtils.copyProperties(data,userVo);

            // 将LocalDateTime转换为Instant，需要指定时区，这里使用系统默认时区
            Instant instant = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant();

            // 转换为毫秒时间戳
            Long timestamp = instant.toEpochMilli();
            userVo.setLastloginTimeVo(timestamp);

            userVo.setExpireTimeVo(data.getLastloginTime().plusMinutes(30).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());

            redisUtil.set(data.getId().toString(),userVo,30);
            session.setAttribute("id", data.getId());
            session.setAttribute("username", data.getUsername());
            map.put("token",jwtToken);
//            menuMapper.getMenuListByUserId(data.getId(),0);
//             权限列表
            List<Menu> menuList = menuService.getMenuListByUserId(data.getId());
            map.put("menuList",menuList);
            return Result.success(map);
        }catch (MyException e){
            throw new MyException(e.getErrorType(),"登录失败");
        }
    }

    @ApiOperation("根据token获取用户信息")
    @GetMapping("/info")
    public Result<User> getUserInfo(@RequestParam("token") String token){
        // 根据token获取用户信息，redis
        UserVo data = userService.getUserInfo(token);
        User user = new User();
        BeanUtils.copyProperties(data,user);

        // 将时间戳转换为Instant对象
        Instant instant = Instant.ofEpochMilli(data.getLastloginTimeVo());
        // 获取系统默认时区
        ZoneId zoneId = ZoneId.systemDefault();
        // 将Instant对象转换为LocalDateTime对象
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
        user.setLastloginTime(localDateTime);

        if(data != null){
            return Result.success(user);
        }
        return Result.fail(20003,"登录信息无效，请重新登录");
    }

    @ApiOperation("退出登录")
    @PostMapping("/logout")
    public Result<?> logout(@RequestHeader("token") String token){
        UserVo data = userService.getUserInfo(token);
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.del(data.getId().toString());
        return Result.success();
    }

    @ApiOperation("用户管理，分页查找所有用户信息")
    @GetMapping("/getList")
    public Result<Map<String,Object>> getUserList(@RequestParam(value = "pageNo") Integer  pageNo){
        Map<String, Object> data= new HashMap<>();
        IPage<User> userIPage = userService.getUserList(pageNo);

        for(User user:userIPage.getRecords()){
            user.setPassword("");
        }
        data.put("userList",userIPage.getRecords());
        data.put("pages",userIPage.getPages());
        data.put("total",userIPage.getTotal());
        return Result.success(data);
    }

    @ApiOperation("用户管理，导出全部用户的信息")
    @GetMapping("/DownloadUserList")
    public void DownloadUserList(HttpServletResponse response) throws IOException {
        List<User> userList = userService.getUserList();
        for (User user : userList) {
            Integer userRole = user.getUserRole();
            user.setUserRoleStr(roleService.getById(userRole).getRoleName());
        }
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("用户信息导出表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(ExcelStyleUtils.getHeadStyle(), ExcelStyleUtils.getContentStyle());

            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), User.class)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet("sheet1")
                    .doWrite(userList);
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSONUtils.toJSONString(map));
        }

    }
    @ApiOperation("用户管理，获取所有用户的id及对应name")
    @GetMapping("/getallUserIdAndUserName")
    public Result<List<Map<String, Object>>> getallUserIdAndUserName() {
        return userService.getallUserIdAndUserName();

    }

    @ApiOperation("用户管理，修改用户密码")
    @PostMapping("/updatePassword")
    public Result<?> updatePassword(Integer id,String password) {
        return userService.updatePassword(id,password);

    }

    @ApiOperation("用户管理，修改用户状态")
    @PostMapping("/updateUserStatus")
    public Result<?> updateStatus(@RequestParam(value = "id") Integer id){
        return userService.updateStatus(id);
    }

    @ApiOperation("用户管理，通过ID获得用户信息")
    @GetMapping("/getUserById/{id}")
    public Result<User> getUserById(@PathVariable("id") Integer id) {
        User user = userService.getById(id);
        return Result.success(user);
    }

    @ApiOperation("用户管理，删除某用户信息")
    @DeleteMapping("/deleteUser/{id}")
    public Result<Object> deleteUserById(@PathVariable("id") Integer id) {
        return userService.deleteUserById(id);
    }

    @ApiOperation("用户管理，用户修改")
    @PostMapping("/updateUserInfo")
    public Result<Void> updateUserInfo(@RequestBody UserRegVo reg) {//@RequestBody是做json字符串的转换
        this.userService.updateUserInfo(reg);
        return Result.success(null);
    }

    @ApiOperation("用户管理，通过用户id获得其拥有的站号")
    @GetMapping("/getStationNosByUid/{id}")
    public Result<Map<String,List<Integer>>> getStationNosByUid(@PathVariable("id") Integer id) {
        Map<String,List<Integer>> res = new HashMap<>();

        List<Integer> list1 = userService.getSteamStationNosByUid(id);
//        List<Integer> list2 = userService.getWaterStationNosByUid(id);
        res.put("蒸汽",list1);
//        res.put("用水",list2);
        return Result.success(res);
    }

    /**
     * app中的模糊搜索下拉框
     * @param likeName
     * @return
     */
    @ApiOperation(value = "（app）模糊查找所有用户信息",notes = "LikeName是全模糊查询")
    @GetMapping("/getUserNameListByLikeName")
    public Result<List<String>> getUserNameListByLikeName(String likeName){
        List<String> infoList = userService.getUserNameListByLikeName(likeName);
        return Result.success(infoList);
    }


    @ApiOperation("(app)用户管理，通过username获得用户信息")
    @GetMapping("/getUserByName/{username}")
    public Result<User> getUserByName(@PathVariable("username") String username) {
        User user = userService.getByName(username);
        return Result.success(user);
    }


    /**
     * (app)收藏/取消某个站点
     * @param uid
     * @param customId
     * @return
     */
    @ApiOperation(value = "(app)收藏/取消某个用户")
    @GetMapping("/collectStation")
    public Result<?> collectStation(Integer uid,Integer customId){
        LambdaQueryWrapper<AppCollection> wp = new LambdaQueryWrapper<>();
        wp.eq(AppCollection::getUserId,uid).eq(AppCollection::getCollectionUser,customId);
        AppCollection appCollection = appCollectionMapper.selectOne(wp);
        if(appCollection!=null){
            appCollectionMapper.deleteById(appCollection);
            return Result.success("取消关注");
        }else {
            AppCollection appCollection1 = new AppCollection();
            appCollection1.setCollectionUser(customId);
            appCollection1.setUserId(uid);
            appCollectionMapper.insert(appCollection1);
            return Result.success("关注成功");
        }
    }

    /**
     * (app)判断某个站点是否被某个用户关注，进行状态回显
     * @param uid
     * @param customId
     * @return
     */
    @ApiOperation(value = "(app)判断某个用户是否被某个用户关注，进行状态回显",notes = "uid是当前app用户的id")
    @GetMapping("/judgeCollectStation")
    public Result<Boolean> judgeCollectStation(Integer uid,Integer customId){
        LambdaQueryWrapper<AppCollection> wp = new LambdaQueryWrapper<>();
        wp.eq(AppCollection::getUserId,uid).eq(AppCollection::getCollectionUser,customId);
        AppCollection appCollection = appCollectionMapper.selectOne(wp);
        if(appCollection!=null){
            return Result.success(true);
        }else {
            return Result.success(false);
        }
    }

    @ApiOperation(value = "(app)我的关注---->获取我的关注的用户的数量")
    @GetMapping("/getCollectionNum")
    public Result<Long> getCollectionNum(Integer uid){
        LambdaQueryWrapper<AppCollection> wp = new LambdaQueryWrapper<>();
        wp.eq(AppCollection::getUserId,uid);
        Long aLong = appCollectionMapper.selectCount(wp);
        return Result.success(aLong);
    }

    @Autowired
    StationInfoMapper stationInfoMapper;
    @ApiOperation(value = "(app)用户总量---->获取所有站点的数量")
    @GetMapping("/getStationNum")
    public Result<Long> getStationNum(){
        LambdaQueryWrapper<StationInfo> wp = new LambdaQueryWrapper<>();
        wp.eq(StationInfo::getIsUse,true);
        Long aLong = stationInfoMapper.selectCount(wp);
        return Result.success(aLong);
    }


}
